/*
 * Copyright 2007 National Bioinformatics Network
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package dgbgui.gui.event;

import java.awt.event.InputEvent;
import java.util.LinkedHashSet;
import java.util.Set;

import dgbgui.gui.widgets.Widget;
import dgbgui.gui.widgets.WidgetStore;
import dgbgui.gui.widgets.visual.QueryWidget;
import dgbgui.gui.widgets.visual.TitleBarWidget;
import dgbgui.modeldocument.Query;
import dgbgui.selection.SelectionManager;
import edu.umd.cs.piccolo.event.PDragSequenceEventHandler;
import edu.umd.cs.piccolo.event.PInputEvent;
import edu.umd.cs.piccolo.event.PInputEventFilter;

public class DragSelectedEventHandler extends PDragSequenceEventHandler implements
CheckConsumedInputEventHandler {
    
    public DragSelectedEventHandler() {
        setEventFilter(new PInputEventFilter(InputEvent.BUTTON1_MASK));
    }
    
    public void startDrag(PInputEvent event) {
        super.startDrag(event);
        if ( ( SelectionManager.getInstance().getSelection(Query.class).size() > 0 ) ) {
            
            // Make sure that a selected query's title bar is under the mouse pointer,
            // so aso to avoid dragging query widgets when some are selected, but
            // shift is being pressed so they are not unselected at this point
            LinkedHashSet<Class> objectPreference = new LinkedHashSet<Class>();
            objectPreference.add(TitleBarWidget.class);
            // Get the titlebar widget
            Widget preferredObj = Widget.findPreferencialObject((event.getCamera().pick(
                    event.getCanvasPosition().getX(),
                    event.getCanvasPosition().getY(),
                    1)).getNodeStackReference(),
                    objectPreference);
            
            // If a title bar is under the pointer, get the query and check if it's selected
            if ( preferredObj != null )  {
                QueryWidget widget = ((QueryWidget)preferredObj.getParentOfClass(QueryWidget.class));
                Query query = WidgetStore.getInstance().getQuery(widget);
                if (SelectionManager.getInstance().getSelection(Query.class).contains(query) ) {
                    m_processed = true;
                    m_draggingSelection = true;
                }
            }
        }
    }
    
    public void endDrag(PInputEvent event) {
        super.endDrag(event);
        if ( ( SelectionManager.getInstance().getSelection(Query.class).size() > 0 ) &&
             m_draggingSelection ) {
            m_processed = true;
            m_draggingSelection = false;
        }

    }

    public void drag(PInputEvent event) {

        if ( ( SelectionManager.getInstance().getSelection(Query.class).size() > 0 ) &&
               m_draggingSelection ) {
            double dx = event.getDelta().width;
            double dy = event.getDelta().height;

            // All the items that are currently selection will be translated
            // by dx,dy
            Set<Object> selectedObjs = SelectionManager.getInstance().getSelection(Query.class);
            Set<Query> selectedNodes = new LinkedHashSet<Query>();
            for ( Object obj : selectedObjs ) {
                selectedNodes.add((Query)obj);
            }
            for ( Query node : selectedNodes ) {
                // Get the visual item of the node
                Set<QueryWidget> widgets = WidgetStore.getInstance().getWidgets(node);
                for ( QueryWidget widget : widgets ) {
                    widget.translate(dx, dy);
                }
            }

            // Only set processed as true when something is selected, otherwise
            // panning will not work
            m_processed = true;
        }
    }

    public boolean eventProcessed(PInputEvent event, int type) {
        m_processed = false;
        processEvent(event,type);
        return m_processed;
    }

    private boolean m_processed;
    private boolean m_draggingSelection = false;

}
